package com.okyai.cms.generate.tag;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.okyai.cms.domain.CmsCustomTag;
import com.okyai.cms.generate.utils.ParserUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * @Author: okyai
 * @Description: 自定义标签
 * @Date: Create in 2020/06/23 9:16
 */

public class CustomTag implements TemplateDirectiveModel {
    protected static BeansWrapper build = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build();
    /*
     * log4j日志记录
     */
    protected final Logger LOG = LoggerFactory.getLogger(this.getClass());

    /**
     * 解析标签用的map
     */
    private Map data;
    /**
     * 标签sql模板
     */
    private CmsCustomTag tag;
    /**
     * 传出的变量名
     */
    private String variableName;

    public CustomTag(Map data, CmsCustomTag tag){
        this.data = data;
        this.tag = tag;
        this.variableName = "field";
    }

    public CustomTag(Map data, CmsCustomTag tag, String variableName){
        this.data = data;
        this.tag = tag;
        this.variableName = variableName;
    }
    @Override
    public void execute(Environment environment, Map params, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
        HashMap<Object, Object> root = CollUtil.newHashMap();
        //历史变量
        //将外部传入的压入
        root.putAll(data);
        //将标签传入参数逐一的压入
        params.forEach((k,v)->{
            if(v instanceof TemplateModel){
                try {
                    root.put(k,build.unwrap((TemplateModel)v));
                } catch (TemplateModelException e) {
                    e.printStackTrace();
                    LOG.error("转换参数错误 key:{} -{}",k,e);
                }
            }
        });
        //压入了栏目则传入sql模板
        TemplateModel column = environment.getVariable(ParserUtil.COLUMN);
        if(column!=null){
            root.put(ParserUtil.COLUMN,build.unwrap(column));
        }

        String sql = ParserUtil.rendering(root,tag.getTagSql());
        NamedParameterJdbcTemplate jdbc = SpringUtil.getBean(NamedParameterJdbcTemplate.class);
        List _list = jdbc.queryForList(sql,CollUtil.newHashMap());
        TemplateModel oldVar = environment.getVariable(variableName);
        //渲染标签
        _list.forEach(x->{
            try {
                TemplateModel columnModel = build.wrap(x);
                //如果自定义了变量则赋值自定义变量
                if(templateModels.length>0){
                    templateModels[0] = columnModel;
                }else {
                    environment.setVariable(variableName, columnModel);
                }
                //压入 以便嵌套使用
                environment.setVariable(ParserUtil.COLUMN, columnModel);
                //渲染
                templateDirectiveBody.render(environment.getOut());
                //渲染完成还原变量
                environment.setVariable(ParserUtil.COLUMN,column);
                environment.setVariable(variableName,oldVar);

            } catch (TemplateModelException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }



}
